package controller

import (
	"gorm.io/gorm"
	"net/http"

	"github.com/example/video_backend/internal/model"
	"github.com/example/video_backend/internal/service"
	"github.com/example/video_backend/pkg/jwt"
	"github.com/example/video_backend/pkg/logger"
	"github.com/gin-gonic/gin"
)

// UserController 用户控制器
type UserController struct {
	userService service.UserService
}

// NewUserController 创建用户控制器实例
func NewUserController(userService service.UserService) *UserController {
	return &UserController{userService: userService}
}

// Register 用户注册
type RegisterRequest struct {
	Username string `json:"username" binding:"required,min=3,max=50"`
	Password string `json:"password" binding:"required,min=6,max=50"`
	Email    string `json:"email" binding:"required,email"`
}

// @Summary 用户注册
// @Description 创建新用户账号
// @Tags 用户
// @Accept json
// @Produce json
// @Param request body RegisterRequest true "注册请求参数"
// @Success 200 {object} Response{data=model.User}
// @Router /api/v1/users/register [post]
func (c *UserController) Register(ctx *gin.Context) {
	var req RegisterRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Error("Register request binding error: " + err.Error())
		ctx.JSON(http.StatusBadRequest, Response{Code: 400, Message: err.Error()})
		return
	}

	user, err := c.userService.Register(ctx, req.Username, req.Password, req.Email)
	if err != nil {
		logger.Error("Register error: " + err.Error())
		ctx.JSON(http.StatusBadRequest, Response{Code: 400, Message: err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, Response{Code: 200, Message: "注册成功", Data: user})
}

// Login 用户登录
type LoginRequest struct {
	Username string `json:"username" binding:"required"`
	Password string `json:"password" binding:"required"`
}

type LoginResponse struct {
	Token string      `json:"token"`
	User  *model.User `json:"user"`
}

// @Summary 用户登录
// @Description 用户账号登录
// @Tags 用户
// @Accept json
// @Produce json
// @Param request body LoginRequest true "登录请求参数"
// @Success 200 {object} Response{data=LoginResponse}
// @Router /api/v1/users/login [post]
func (c *UserController) Login(ctx *gin.Context) {
	var req LoginRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Error("Login request binding error: " + err.Error())
		ctx.JSON(http.StatusBadRequest, Response{Code: 400, Message: err.Error()})
		return
	}

	user, err := c.userService.Login(ctx, req.Username, req.Password)
	if err != nil {
		logger.Error("Login error: " + err.Error())
		ctx.JSON(http.StatusUnauthorized, Response{Code: 401, Message: err.Error()})
		return
	}

	// 生成JWT token
	token, err := jwt.GenerateToken(user.ID, user.Username, user.IsAdmin)
	if err != nil {
		logger.Error("Generate token error: " + err.Error())
		ctx.JSON(http.StatusInternalServerError, Response{Code: 500, Message: "生成token失败"})
		return
	}

	response := LoginResponse{
		Token: token,
		User:  user,
	}

	ctx.JSON(http.StatusOK, Response{Code: 200, Message: "登录成功", Data: response})
}

// GetUserInfo 获取用户信息
// @Summary 获取用户信息
// @Description 获取当前登录用户的信息
// @Tags 用户
// @Accept json
// @Produce json
// @Security Bearer
// @Success 200 {object} Response{data=model.User}
// @Router /api/v1/users/info [get]
func (c *UserController) GetUserInfo(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, Response{Code: 401, Message: "未登录"})
		return
	}

	uid, ok := userID.(uint)
	if !ok {
		ctx.JSON(http.StatusUnauthorized, Response{Code: 401, Message: "无效的用户ID"})
		return
	}

	user, err := c.userService.GetUserInfo(ctx, uid)
	if err != nil {
		logger.Error("Get user info error: " + err.Error())
		ctx.JSON(http.StatusInternalServerError, Response{Code: 500, Message: "获取用户信息失败"})
		return
	}

	if user == nil {
		ctx.JSON(http.StatusNotFound, Response{Code: 404, Message: "用户不存在"})
		return
	}

	ctx.JSON(http.StatusOK, Response{Code: 200, Message: "获取成功", Data: user})
}

// UpdateUserInfo 更新用户信息
type UpdateUserInfoRequest struct {
	Avatar string `json:"avatar"`
	Bio    string `json:"bio" binding:"max=500"`
	Email  string `json:"email" binding:"email"`
}

// @Summary 更新用户信息
// @Description 更新当前登录用户的信息
// @Tags 用户
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body UpdateUserInfoRequest true "更新用户信息请求参数"
// @Success 200 {object} Response{data=model.User}
// @Router /api/v1/users/info [put]
func (c *UserController) UpdateUserInfo(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, Response{Code: 401, Message: "未登录"})
		return
	}

	uid, ok := userID.(uint)
	if !ok {
		ctx.JSON(http.StatusUnauthorized, Response{Code: 401, Message: "无效的用户ID"})
		return
	}

	var req UpdateUserInfoRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Error("Update user info request binding error: " + err.Error())
		ctx.JSON(http.StatusBadRequest, Response{Code: 400, Message: err.Error()})
		return
	}

	user := &model.User{
		Model: gorm.Model{
			ID: uid,
		},
		Avatar: req.Avatar,
		Bio:    req.Bio,
		Email:  req.Email,
	}

	if err := c.userService.UpdateUserInfo(ctx, user); err != nil {
		logger.Error("Update user info error: " + err.Error())
		ctx.JSON(http.StatusInternalServerError, Response{Code: 500, Message: err.Error()})
		return
	}

	// 获取更新后的用户信息
	updatedUser, err := c.userService.GetUserInfo(ctx, uid)
	if err != nil {
		logger.Error("Get updated user info error: " + err.Error())
		ctx.JSON(http.StatusInternalServerError, Response{Code: 500, Message: "获取更新后的用户信息失败"})
		return
	}

	ctx.JSON(http.StatusOK, Response{Code: 200, Message: "更新成功", Data: updatedUser})
}

// ChangePassword 修改密码
type ChangePasswordRequest struct {
	OldPassword string `json:"old_password" binding:"required"`
	NewPassword string `json:"new_password" binding:"required,min=6,max=50"`
}

// @Summary 修改密码
// @Description 修改当前登录用户的密码
// @Tags 用户
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body ChangePasswordRequest true "修改密码请求参数"
// @Success 200 {object} Response
// @Router /api/v1/users/password [put]
func (c *UserController) ChangePassword(ctx *gin.Context) {
	// 从上下文中获取用户ID
	userID, exists := ctx.Get("userID")
	if !exists {
		ctx.JSON(http.StatusUnauthorized, Response{Code: 401, Message: "未登录"})
		return
	}

	uid, ok := userID.(uint)
	if !ok {
		ctx.JSON(http.StatusUnauthorized, Response{Code: 401, Message: "无效的用户ID"})
		return
	}

	var req ChangePasswordRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logger.Error("Change password request binding error: " + err.Error())
		ctx.JSON(http.StatusBadRequest, Response{Code: 400, Message: err.Error()})
		return
	}

	if err := c.userService.ChangePassword(ctx, uid, req.OldPassword, req.NewPassword); err != nil {
		logger.Error("Change password error: " + err.Error())
		ctx.JSON(http.StatusBadRequest, Response{Code: 400, Message: err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, Response{Code: 200, Message: "密码修改成功"})
}
